#ifndef _USE_RES_H
#define _USE_RES_H
#define _countof(array) (sizeof(array)/sizeof(array[0]))
#ifdef _UNICODE
#define CHAR_FUDGE 1    // one TCHAR unused is good enough
#else
#define CHAR_FUDGE 2    // two BYTES unused for case of DBC last char
#endif
#include "resourcedefine.h"
#include <afx.h>

class CRString : public CString
{
public:
	CRString(){};
	CRString(const CRString& stringSrc) : CString(stringSrc){};
	CRString(const CString& stringSrc) : CString(stringSrc){};
	// from a single character
	CRString(TCHAR ch, int nRepeat = 1) : CString(ch,nRepeat){};
	// from an ANSI string (converts to TCHAR)
	CRString(LPCSTR lpsz) : CString(lpsz){};
	// from a UNICODE string (converts to TCHAR)
	CRString(LPCWSTR lpsz) : CString (lpsz) {};
	// subset of characters from an ANSI string (converts to TCHAR)
	CRString(LPCSTR lpch, int nLength) : CString (lpch,nLength){};
	// subset of characters from a UNICODE string (converts to TCHAR)
	CRString(LPCWSTR lpch, int nLength) : CString (lpch,nLength){};
	// from unsigned characters
	CRString(const unsigned char* psz) : CString (psz) {};

// Attributes & Operations

	// get data length
	int GetLength() const { return CString :: GetLength();};
	// TRUE if zero length
	BOOL IsEmpty() const { return CString :: IsEmpty();};
	// clear contents to empty
	void Empty() { CString :: Empty();};

	// return single character at zero-based index
	TCHAR GetAt(int nIndex) const { return CString :: GetAt(nIndex); };
	// return single character at zero-based index
	TCHAR operator[](int nIndex) const { return CString :: operator[](nIndex);};
	// set a single character at zero-based index
	void SetAt(int nIndex, TCHAR ch) { CString::SetAt(nIndex,ch);};
	// return pointer to const string
	operator LPCTSTR() const {return CString::operator LPCTSTR();};

	// overloaded assignment

	// ref-counted copy from another CRString
	const CRString& operator=(const CRString& stringSrc) { return (CRString &) CString::operator =(stringSrc);};
	const CRString& operator=(const CString& stringSrc) { return (CRString &) CString::operator =(stringSrc);};
	// set string content to single character
	const CRString& operator=(TCHAR ch){ return (CRString &) CString::operator =(ch);};
#ifdef _UNICODE
	const CRString& operator=(char ch){ return CString::operator =(ch);};
#endif
	// copy string content from ANSI string (converts to TCHAR)
	const CRString& operator=(LPCSTR lpsz){ return (CRString &) CString::operator =(lpsz);};
	// copy string content from UNICODE string (converts to TCHAR)
	const CRString& operator=(LPCWSTR lpsz){ return (CRString &) CString::operator =(lpsz);};
	// copy string content from unsigned chars
	const CRString& operator=(const unsigned char* psz){ return (CRString &) CString::operator =(psz);};

	// string concatenation

	// concatenate from another CRString
	const CRString& operator+=(const CRString& string){ return (CRString &) CString::operator +=(string);};
	const CRString& operator+=(const CString& string){ return (CRString &) CString::operator +=(string);};

	// concatenate a single character
	const CRString& operator+=(TCHAR ch) { return (CRString &) CString::operator +=(ch);};
#ifdef _UNICODE
	// concatenate an ANSI character after converting it to TCHAR
	const CRString& operator+=(char ch){ return (CRString &) CString::operator +=(ch);};
#endif
	// concatenate a UNICODE character after converting it to TCHAR
	const CRString& operator+=(LPCTSTR lpsz){ return (CRString &) CString::operator +=(lpsz);};

	void AFX_CDECL Format(UINT nFormatID, ...)
	{
		CRString strFormat;
		INIT_RESOURCE
		VERIFY(strFormat.LoadString(nFormatID) != 0);
		va_list argList;
		va_start(argList, nFormatID);
		FormatV(strFormat, argList);
		END_RESOURCE
		va_end(argList);
	};
	void AFX_CDECL Format(LPCTSTR lpszFormat, ...)
	{
		va_list argList;
		va_start(argList, lpszFormat);
		FormatV(lpszFormat, argList);
		va_end(argList);
	};
	BOOL inline LoadString(UINT nID)
	{
		BOOL bResult = TRUE;
		INIT_RESOURCE
			bResult = CString::LoadString(nID);
		END_RESOURCE
			return bResult;
	};
};
class CRMenu : public CMenu
{
public:
	int inline LoadMenu(UINT nID)
	{
		INIT_RESOURCE
			CMenu::LoadMenu(nID);
		END_RESOURCE
	};
};
#endif